package com.dd.cloud.common.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.dd.cloud.common.config.common.SpringContextJobUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.lang.Nullable;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author: HuYi.Zhang
 * @create: 2018-04-24 17:20
 **/
@Slf4j
public class JsonUtils {

    @Nullable
    public static String serialize(Object obj) {
        if (obj == null) {
            return null;
        }
        if (obj.getClass() == String.class) {
            return (String) obj;
        }
        try {
            ObjectMapper objectMapper = SpringContextJobUtil.getBean("objectMapper", ObjectMapper.class);
            return objectMapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("json序列化出错：" + obj, e);
            return null;
        }
    }

    @Nullable
    public static <T> T parse(String json, Class<T> tClass) {
        try {
            ObjectMapper objectMapper = SpringContextJobUtil.getBean("objectMapper", ObjectMapper.class);
            return objectMapper.readValue(json, tClass);
        } catch (IOException e) {
            log.error("json解析出错：" + json, e);
            return null;
        }
    }

    @Nullable
    public static <E> List<E> parseList(String json, Class<E> eClass) {
        try {
            ObjectMapper objectMapper = SpringContextJobUtil.getBean("objectMapper", ObjectMapper.class);
            return objectMapper.readValue(json, objectMapper.getTypeFactory().constructCollectionType(List.class, eClass));
        } catch (IOException e) {
            log.error("json解析出错：" + json, e);
            return null;
        }
    }

    @Nullable
    public static <K, V> Map<K, V> parseMap(String json, Class<K> kClass, Class<V> vClass) {
        try {
            ObjectMapper objectMapper = SpringContextJobUtil.getBean("objectMapper", ObjectMapper.class);
            return objectMapper.readValue(json, objectMapper.getTypeFactory().constructMapType(Map.class, kClass, vClass));
        } catch (IOException e) {
            log.error("json解析出错：" + json, e);
            return null;
        }
    }

    @Nullable
    public static <T> T nativeRead(String json, TypeReference<T> type) {
        try {
            ObjectMapper objectMapper = SpringContextJobUtil.getBean("objectMapper", ObjectMapper.class);
            return objectMapper.readValue(json, type);
        } catch (IOException e) {
            log.error("json解析出错：" + json, e);
            return null;
        }
    }

    /**
     * @param @param str
     * @param @param clazz
     * @return T
     * @Title: strToObject
     * @Description: json字符串转Object对象
     */
    public static <T> T strToObject(String str, Class<T> clazz) {
        T t = null;
        try {
            ObjectMapper objectMapper = SpringContextJobUtil.getBean("objectMapper", ObjectMapper.class);
            t = objectMapper.readValue(str, clazz);
            return t;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return t;
    }


    /**
     * @param @param t
     * @return String
     * @Title: objectToStr
     * @Description: Object对象转json字符串
     */
    public static <T> String objectToStr(T t) {
        String str = null;
        try {
            ObjectMapper objectMapper = SpringContextJobUtil.getBean("objectMapper", ObjectMapper.class);
            str = objectMapper.writeValueAsString(t);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }


    /**
     * @param @param t
     * @return String
     * @Title: objectToStr
     * @Description: Object对象转json字符串 驼峰转下划线
     */
    public static <T> String objectToStrStrategy(T t) {
        // 驼峰转下划线 userName -> user_name
        String str = null;
        try {
            ObjectMapper objectMapper = SpringContextJobUtil.getBean("objectMapperSnake", ObjectMapper.class);
            str = objectMapper.writeValueAsString(t);
            return str;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return str;
    }


    /**
     * @param @param str
     * @param @param clazz
     * @return List<T>
     * @Title: strToList
     * @Description: json字符串转list对象集合
     */
    public static <T> List<T> strToList(String str, Class<T> clazz) {
        JSONArray json = JSONArray.parseArray(str);
        JSONObject object = null;
        T t;
        List<T> list = new ArrayList<>();
        for (int i = 0; i < json.size(); i++) {
            t = JSONObject.parseObject(JSON.toJSONString(object), clazz);
            list.add(t);
        }
        return list;
    }


    /**
     * 用于Fiegn 远程调用返回对象或集合获取值时  需使用此方法转化
     * 异常信息 java.util.LinkedHashMap cannot be cast to **
     *
     * @param object
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T objectToVo(Object object, Class<T> clazz) {
        //先转成JSON对象
        JSONObject jsonObject = (JSONObject) JSONObject.toJSON(object);
        //JSON对象转换成Java对象
        return JSONObject.toJavaObject(jsonObject, clazz);
    }
}
